﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ExpressionUtil.Extension;

namespace ExpressionUtil.UnitTest
{
    /// <summary>
    /// ExtensionFunctionUnitTest 的摘要说明
    /// </summary>
    [TestClass]
    public class ExtensionFunctionUnitTest
    {
        public ExtensionFunctionUnitTest()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///获取或设置测试上下文，该上下文提供
        ///有关当前测试运行及其功能的信息。
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region 附加测试属性
        //
        // 编写测试时，还可使用以下附加属性:
        //
        // 在运行类中的第一个测试之前使用 ClassInitialize 运行代码
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // 在类中的所有测试都已运行之后使用 ClassCleanup 运行代码
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // 在运行每个测试之前，使用 TestInitialize 来运行代码
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // 在每个测试运行完之后，使用 TestCleanup 来运行代码
        [TestCleanup()]
        public void MyTestCleanup() 
        {
            ExtensionFunction.Unregister("TestFuncNoneParam");
            ExtensionFunction.Unregister("TestFunc");
        }
        //
        #endregion

        [TestMethod]
        public void ExtensionFunctionNoneParamTestDecimal()
        {
            ExtensionFunction func = new ExtensionFunction("TestFuncNoneParam", this.TestFuncNoneParamHandlerDecimal);
            ExtensionFunction.Register(func);
            Expression exp = new Expression("TestFuncNoneParam()");
            Assert.AreEqual(exp.DecimalResult, 0);
        }

        [TestMethod]
        [ExpectedException(typeof(FormatException), "无参参数个数测试")]
        public void ExtensionFunctionNoneParamErrorTestDecimal()
        {
            ExtensionFunction func = new ExtensionFunction("TestFuncNoneParam", this.TestFuncNoneParamHandlerDecimal);
            ExtensionFunction.Register(func);
            Expression exp = new Expression("TestFuncNoneParam(1,2,3,4,5)");
            exp.Compile();
        }

        [TestMethod]
        public void ExtensionFunctionParamVariableTestDecimal()
        {
            ExtensionFunction func = new ExtensionFunction("TestFunc", this.TestFuncHandlerDecimal);
            func.ParameterCountType = ParameterCountType.Variable;
            ExtensionFunction.Register(func);
            Expression exp = new Expression("TestFunc(1,2,3,4,5)");
            Assert.AreEqual(exp.DecimalResult, 15);
        }

        [TestMethod]
        public void ExtensionFunctionParamFixedTestDecimal()
        {
            ExtensionFunction func = new ExtensionFunction("TestFunc", this.TestFuncHandlerDecimal);
            func.ParameterCountType = ParameterCountType.Fixed;
            func.ParameterCount = 5;
            ExtensionFunction.Register(func);
            Expression exp = new Expression("TestFunc(1,2,3,4,5)");
            Assert.AreEqual(exp.DecimalResult, 15);
        }

        [TestMethod]
        [ExpectedException(typeof(FormatException), "参数个数测试")]
        public void ExtensionFunctionErrorTestDecimal()
        {
            ExtensionFunction func = new ExtensionFunction("TestFunc", this.TestFuncHandlerDecimal);
            func.ParameterCountType = ParameterCountType.Fixed;
            func.ParameterCount = 10;
            ExtensionFunction.Register(func);
            Expression exp = new Expression("TestFunc(1,2,3,4,5)");
            exp.Compile();
        }

        [TestMethod]
        public void ExtensionFunctionNoneParamTestBool()
        {
            ExtensionFunction func = new ExtensionFunction("TestFuncNoneParam", this.TestFuncNoneParamHandlerBool);
            ExtensionFunction.Register(func);
            Expression exp = new Expression("TestFuncNoneParam()");
            Assert.AreEqual(exp.BoolResult, false);
        }

        private void TestFuncNoneParamHandlerDecimal(ExtExecuteContext context)
        {
            if (context.Parameters.Count > 0)
            {
                context.ReturnValueInfo.DecimalData = 1;
            }
            else
            {
                context.ReturnValueInfo.DecimalData = 0;
            }
        }

        private void TestFuncHandlerDecimal(ExtExecuteContext context)
        {
            decimal sum = 0;
            for (int i = 0; i < context.Parameters.Count; i++)
            {
                if (context.Parameters[i].DecimalData != i + 1)
                {
                    throw new Exception("测试参数位置不正确.");
                }
                sum += context.Parameters[i].DecimalData;
            }
            context.ReturnValueInfo.DecimalData = sum;
        }

        private void TestFuncNoneParamHandlerBool(ExtExecuteContext context)
        {
            if (context.Parameters.Count > 0)
            {
                context.ReturnValueInfo.BooleanData = true;
            }
            else
            {
                context.ReturnValueInfo.BooleanData = false;
            }
        }
    }
}
